home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH19 / SHARDMEM.ASM < prev    next >
Encoding:
Assembly Source File  |  1994-07-17  |  7.8 KB  |  373 lines

  1. ; SHARDMEM.ASM
  2. ;
  3. ; This TSR sets aside a 64K shared memory region for other processes to use.
  4. ;
  5. ; Usage:
  6. ;
  7. ;    SHARDMEM        - Loads resident portion and activates
  8. ;                  shared memory capabilities.
  9. ;
  10. ;    SHARDMEM REMOVE        - Removes shared memory TSR from memory.
  11. ;
  12. ; This TSR checks to make sure there isn't a copy already active in
  13. ; memory.  When removing itself from memory, it makes sure there are
  14. ; no other interrupts chained into INT 2Fh before doing the remove.
  15. ;
  16. ;
  17. ;
  18. ; The following segments must appear in this order and before the
  19. ; Standard Library includes.
  20.  
  21. ResidentSeg    segment    para public 'Resident'
  22. ResidentSeg    ends
  23.  
  24. SharedMemory    segment    para public 'Shared'
  25. SharedMemory    ends
  26.  
  27. EndResident    segment    para public 'EndRes'
  28. EndResident    ends
  29.  
  30.         .xlist
  31.         .286
  32.         include     stdlib.a
  33.         includelib    stdlib.lib
  34.         .list
  35.  
  36.  
  37. ; Resident segment that holds the TSR code:
  38.  
  39. ResidentSeg    segment    para public 'Resident'
  40.         assume    cs:ResidentSeg, ds:nothing
  41.  
  42. ; Int 2Fh ID number for this TSR:
  43.  
  44. MyTSRID        byte    0
  45.         byte    0        ;Padding so we can print it.
  46.  
  47. ; PSP is the psp address for this program.
  48.  
  49. PSP        word    0
  50.  
  51. OldInt2F    dword    ?
  52.  
  53.  
  54. ; MyInt2F-    Provides int 2Fh (multiplex interrupt) support for this
  55. ;        TSR.  The multiplex interrupt recognizes the following
  56. ;        subfunctions (passed in AL):
  57. ;
  58. ;        00h- Verify presence.      Returns 0FFh in AL and a pointer
  59. ;                    to an ID string in es:di if the
  60. ;                    TSR ID (in AH) matches this
  61. ;                    particular TSR.
  62. ;
  63. ;        01h- Remove.        Removes the TSR from memory.
  64. ;                    Returns 0 in AL if successful,
  65. ;                    1 in AL if failure.
  66. ;
  67. ;        10h- Return Seg Adrs.    Returns the segment address of the
  68. ;                    shared segment in ES.
  69.  
  70. MyInt2F        proc    far
  71.         assume    ds:nothing
  72.  
  73.         cmp    ah, MyTSRID    ;Match our TSR identifier?
  74.         je    YepItsOurs
  75.         jmp    OldInt2F
  76.  
  77. ; Okay, we know this is our ID, now check for a verify, remove, or
  78. ; return segment call.
  79.  
  80. YepItsOurs:    cmp    al, 0        ;Verify Call
  81.         jne    TryRmv
  82.         mov    al, 0ffh    ;Return success.
  83.         lesi    IDString
  84.         iret            ;Return back to caller.
  85.  
  86. IDString    byte    "Static Shared Memory TSR",0
  87.  
  88. TryRmv:        cmp    al, 1        ;Remove call.
  89.         jne    TryRetSeg
  90.  
  91. ; See if we can remove this TSR:
  92.  
  93.         push    es
  94.         mov    ax, 0
  95.         mov    es, ax
  96.         cmp    word ptr es:[2Fh*4], offset MyInt2F
  97.         jne    TRDone
  98.         cmp    word ptr es:[2Fh*4 + 2], seg MyInt2F
  99.         je    CanRemove    ;Branch if we can.
  100. TRDone:        mov    ax, 1        ;Return failure for now.
  101.         pop    es
  102.         iret
  103.  
  104. ; Okay, they want to remove this guy *and* we can remove it from memory.
  105. ; Take care of all that here.
  106.  
  107.         assume    ds:ResidentSeg
  108.  
  109. CanRemove:    push    ds
  110.         pusha
  111.         cli            ;Turn off the interrupts while
  112.         mov    ax, 0        ; we mess with the interrupt
  113.         mov    es, ax        ; vectors.
  114.         mov    ax, cs
  115.         mov    ds, ax
  116.  
  117.         mov    ax, word ptr OldInt2F
  118.         mov    es:[2Fh*4], ax
  119.         mov    ax, word ptr OldInt2F+2
  120.         mov    es:[2Fh*4 + 2], ax
  121.  
  122.  
  123. ; Okay, one last thing before we quit- Let's give the memory allocated
  124. ; to this TSR back to DOS.
  125.  
  126.         mov    ds, PSP
  127.         mov    es, ds:[2Ch]        ;Ptr to environment block.
  128.         mov    ah, 49h            ;DOS release memory call.
  129.         int    21h
  130.  
  131.         mov    ax, ds            ;Release program code space.
  132.         mov    es, ax
  133.         mov    ah, 49h
  134.         int    21h
  135.  
  136.         popa
  137.         pop    ds
  138.         pop    es
  139.         mov    ax, 0            ;Return Success.
  140.         iret
  141.  
  142. ; See if they want us to return the segment address of our shared segment
  143. ; here.
  144.  
  145. TryRetSeg:    cmp    al, 10h            ;Return Segment Opcode
  146.         jne     IllegalOp
  147.         mov    ax, SharedMemory
  148.         mov    es, ax
  149.         mov    ax, 0            ;Return success
  150.         clc
  151.         iret
  152.  
  153. ; They called us with an illegal subfunction value.  Try to do as little
  154. ; damage as possible.
  155.  
  156. IllegalOp:    mov    ax, 0        ;Who knows what they were thinking?
  157.         iret
  158. MyInt2F        endp
  159.         assume    ds:nothing
  160. ResidentSeg    ends
  161.  
  162.  
  163. ; Here's the segment that will actually hold the shared data.
  164.  
  165. SharedMemory    segment    para public 'Shared'
  166.         db    0FFFFh dup (?)
  167. SharedMemory    ends
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174. cseg        segment    para public 'code'
  175.         assume    cs:cseg, ds:ResidentSeg
  176.  
  177. ; SeeIfPresent-    Checks to see if our TSR is already present in memory.
  178. ;        Sets the zero flag if it is, clears the zero flag if
  179. ;        it is not.
  180.  
  181. SeeIfPresent    proc    near
  182.         push    es
  183.         push    ds
  184.         push    di
  185.         mov    cx, 0ffh        ;Start with ID 0FFh.
  186. IDLoop:        mov    ah, cl
  187.         push    cx
  188.         mov    al, 0            ;Verify presence call.
  189.         int    2Fh
  190.         pop    cx
  191.         cmp    al, 0            ;Present in memory?
  192.         je    TryNext
  193.         strcmpl
  194.         byte    "Static Shared Memory TSR",0
  195.         je    Success
  196.  
  197. TryNext:    dec    cl            ;Test USER IDs of 80h..FFh
  198.         js    IDLoop
  199.         cmp    cx, 0            ;Clear zero flag.
  200. Success:    pop    di
  201.         pop    ds
  202.         pop    es
  203.         ret
  204. SeeIfPresent    endp
  205.  
  206.  
  207.  
  208. ; FindID-    Determines the first (well, last actually) TSR ID available
  209. ;        in the multiplex interrupt chain.  Returns this value in
  210. ;        the CL register.
  211. ;
  212. ;        Returns the zero flag set if it locates an empty slot.
  213. ;        Returns the zero flag clear if failure.
  214.  
  215. FindID        proc    near
  216.         push    es
  217.         push    ds
  218.         push    di
  219.  
  220.         mov    cx, 0ffh        ;Start with ID 0FFh.
  221. IDLoop:        mov    ah, cl
  222.         push    cx
  223.         mov    al, 0            ;Verify presence call.
  224.         int    2Fh
  225.         pop    cx
  226.         cmp    al, 0            ;Present in memory?
  227.         je    Success
  228.         dec    cl            ;Test USER IDs of 80h..FFh
  229.         js    IDLoop
  230.         xor    cx, cx
  231.         cmp    cx, 1            ;Clear zero flag
  232. Success:    pop    di
  233.         pop    ds
  234.         pop    es
  235.         ret
  236. FindID        endp
  237.  
  238.  
  239.  
  240. Main        proc
  241.         meminit
  242.  
  243.         mov    ax, ResidentSeg
  244.         mov    ds, ax
  245.  
  246.         mov    ah, 62h            ;Get this program's PSP
  247.         int    21h            ; value.
  248.         mov    PSP, bx
  249.  
  250. ; Before we do anything else, we need to check the command line
  251. ; parameters.  If there is one, and it is the word "REMOVE", then remove
  252. ; the resident copy from memory using the multiplex (2Fh) interrupt.
  253.  
  254.         argc
  255.         cmp    cx, 1            ;Must have 0 or 1 parms.
  256.         jb    TstPresent
  257.         je    DoRemove
  258. Usage:        print
  259.         byte    "Usage:",cr,lf
  260.         byte    "       shardmem",cr,lf
  261.         byte    "or     shardmem REMOVE",cr,lf,0
  262.         ExitPgm
  263.  
  264.  
  265. ; Check for the REMOVE command.
  266.  
  267. DoRemove:    mov    ax, 1
  268.         argv
  269.         stricmpl
  270.         byte    "REMOVE",0
  271.         jne    Usage
  272.  
  273.         call    SeeIfPresent
  274.         je    RemoveIt
  275.         print
  276.         byte    "TSR is not present in memory, cannot remove"
  277.         byte    cr,lf,0
  278.         ExitPgm
  279.  
  280. RemoveIt:    mov    MyTSRID, cl
  281.         printf
  282.         byte    "Removing TSR (ID #%d) from memory...",0
  283.         dword    MyTSRID
  284.  
  285.         mov    ah, cl
  286.         mov    al, 1            ;Remove cmd, ah contains ID
  287.         int    2Fh
  288.         cmp    al, 1            ;Succeed?
  289.         je    RmvFailure
  290.         print
  291.         byte    "removed.",cr,lf,0
  292.         ExitPgm
  293.  
  294. RmvFailure:    print
  295.         byte    cr,lf
  296.         byte    "Could not remove TSR from memory.",cr,lf
  297.         byte    "Try removing other TSRs in the reverse order "
  298.         byte    "you installed them.",cr,lf,0
  299.         ExitPgm
  300.  
  301.  
  302.  
  303. ; Okay, see if the TSR is already in memory.  If so, abort the
  304. ; installation process.
  305.  
  306. TstPresent:     call    SeeIfPresent
  307.         jne    GetTSRID
  308.         print
  309.         byte    "TSR is already present in memory.",cr,lf
  310.         byte    "Aborting installation process",cr,lf,0
  311.         ExitPgm
  312.  
  313.  
  314. ; Get an ID for our TSR and save it away.
  315.  
  316. GetTSRID:    call    FindID
  317.         je    GetFileName
  318.         print
  319.         byte    "Too many resident TSRs, cannot install",cr,lf,0
  320.         ExitPgm
  321.  
  322.  
  323. ; Things look cool so far, so install the interrupts
  324.  
  325. GetFileName:    mov    MyTSRID, cl
  326.         print
  327.         byte    "Installing interrupts...",0
  328.  
  329.  
  330. ; Patch into the INT 2Fh interrupt chain.
  331.  
  332.         cli                ;Turn off interrupts!
  333.         mov    ax, 0
  334.         mov    es, ax
  335.         mov    ax, es:[2Fh*4]
  336.         mov    word ptr OldInt2F, ax
  337.         mov     ax, es:[2Fh*4 + 2]
  338.         mov    word ptr OldInt2F+2, ax
  339.         mov    es:[2Fh*4], offset MyInt2F
  340.         mov    es:[2Fh*4+2], seg ResidentSeg
  341.         sti                ;Okay, ints back on.
  342.  
  343. ; We're hooked up, the only thing that remains is to zero out the shared
  344. ; memory segment and then terminate and stay resident.
  345.  
  346.         printf
  347.         byte    "Installed, TSR ID #%d.",cr,lf,0
  348.         dword    MyTSRID
  349.  
  350.         mov    ax, SharedMemory    ;Zero out the shared
  351.         mov    es, ax            ; memory segment.
  352.         mov    cx, 32768
  353.         xor    ax, ax
  354.         mov    di, ax
  355.     rep    stosw
  356.  
  357.  
  358.         mov    dx, EndResident        ;Compute size of program.
  359.         sub    dx, PSP
  360.         mov    ax, 3100h        ;DOS TSR command.
  361.         int    21h
  362. Main        endp
  363. cseg        ends
  364.  
  365. sseg        segment    para stack 'stack'
  366. stk        db    256 dup (?)
  367. sseg        ends
  368.  
  369. zzzzzzseg    segment    para public 'zzzzzz'
  370. LastBytes    db    16 dup (?)
  371. zzzzzzseg    ends
  372.         end    Main
  373.